using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;

namespace SpellCenter.UI.FileChoosing
{
    public partial class BackNextCancelControl : UserControl
    {
        private readonly BackNextCancelControlPM _model;

        public BackNextCancelControl(int pages)
        {
            InitializeComponent();
            _model = new BackNextCancelControlPM(pages);
            _prevButton.Enabled = false;
            RegisterEvents();
        }

        /// <summary>
        /// This is a really ghetto constructor.  It's only existence is for the purpose of making visual 
        /// studio designer happy.
        /// </summary>
        internal BackNextCancelControl() :this(2) { }

        public int PageNumber
        {
            get { return _model.PageNumber; }
        }

        public void Reset()
        {
            _model.Reset();
            UpdateFromModel();
        }

        public void EnableNextPageButton(bool enable)
        {
            _nextButton.Enabled = enable;
        }

        #region Events

        private void RegisterEvents()
        {
            _nextButton.Click += NextButton_Click;
            _prevButton.Click += PrevButton_Click;
            _cancelButton.Click += CancelButton_Click;
            Resize += Control_Resize;
        }

        private void Control_Resize(object sender, EventArgs e)
        {
            _cancelButton.Location = new Point(ClientRectangle.Right - _cancelButton.Width, ClientRectangle.Top);
            _nextButton.Location = new Point(_cancelButton.Left - (10 + _nextButton.Width), ClientRectangle.Top);
            _prevButton.Location = new Point(_nextButton.Left - _prevButton.Width, ClientRectangle.Top);
        }

        private void CancelButton_Click(object sender, EventArgs e)
        {
            OnCancel(EventArgs.Empty);
        }

        private void UpdateFromModel()
        {
            _nextButton.Text = _model.NextText;
            _prevButton.Enabled = _model.BackEnabled;
        }

        private void PrevButton_Click(object sender, EventArgs e)
        {
            _model.ToPrevPage();
            UpdateFromModel();
            OnPageChanged(EventArgs.Empty);
        }

        private void NextButton_Click(object sender, EventArgs e)
        {
            if(IsValid(_model.PageNumber))
            {
                _model.ToNextPage();
                UpdateFromModel();
                OnPageChanged(EventArgs.Empty);
            }
        }

        public event EventHandler Cancel;

        protected void OnCancel(EventArgs e)
        {
            EventHandler handler = Cancel;
            if (handler != null)
            {
                handler(this, e);
            }
        }

        public event EventHandler PageChanged;

        protected void OnPageChanged(EventArgs e)
        {
            EventHandler handler = PageChanged;
            if (handler != null)
            {
                handler(this, e);
            }
            if(_validators.ContainsKey(PageNumber))
            {
                
            }
        }

        #endregion


        #region Validators

        private readonly Dictionary<int, List<IPageValidator>> _validators = new Dictionary<int, List<IPageValidator>>();
        public void AddValidator(IPageValidator validator, int pageID)
        {
            if(!_validators.ContainsKey(pageID))
                _validators.Add(pageID, new List<IPageValidator>());
            Debug.Assert(_validators[pageID] != null);

            _validators[pageID].Add(validator);
            validator.Valid += Validators_Valid;
            validator.Invalid += Validators_Invalid;
        }

        private void Validators_Invalid(object sender, PageNextEventArgs e)
        {
            _nextButton.Enabled = false;
        }

        private void Validators_Valid(object sender, PageNextEventArgs e)
        {
            if(IsValid(e.Page))
            {
                _nextButton.Enabled = true;
            }
        }

        private bool IsValid(int page)
        {
            if(_validators.ContainsKey(page))
            {
                foreach (IPageValidator validator in _validators[page])
                {
                    if (!validator.IsValid())
                        return false;
                }
            }
            return true;
        }
        public class PageNextEventArgs : EventArgs
        {
            public readonly int Page;
            public PageNextEventArgs(int page)
            {
                Page = page;
            }
        }
        public delegate void PageNextEventHandler(object sender, PageNextEventArgs e);
        public interface IPageValidator
        {
            bool IsValid();
            event PageNextEventHandler Valid;
            event PageNextEventHandler Invalid;
        }

        #endregion

    }

}
